aboutsummaryrefslogtreecommitdiff
path: root/src/app/manga/[title]/[id]
diff options
context:
space:
mode:
authorreal-zephex <[email protected]>2024-03-25 11:33:09 +0530
committerreal-zephex <[email protected]>2024-03-25 11:33:09 +0530
commit9202a2b6790e57dc35d0563d014e89d981a65e37 (patch)
treef2258b96400d6df9753c2c52531ba7f8897b9fa3 /src/app/manga/[title]/[id]
parentfix: requests are revalidated after 30 mins. this prevents stale data from be... (diff)
downloaddramalama-9202a2b6790e57dc35d0563d014e89d981a65e37.tar.xz
dramalama-9202a2b6790e57dc35d0563d014e89d981a65e37.zip
feature added: mangas are now available
Diffstat (limited to 'src/app/manga/[title]/[id]')
-rw-r--r--src/app/manga/[title]/[id]/[read]/page.jsx51
-rw-r--r--src/app/manga/[title]/[id]/[read]/read.module.css43
-rw-r--r--src/app/manga/[title]/[id]/buttons.jsx28
-rw-r--r--src/app/manga/[title]/[id]/info.module.css135
-rw-r--r--src/app/manga/[title]/[id]/page.jsx102
5 files changed, 359 insertions, 0 deletions
diff --git a/src/app/manga/[title]/[id]/[read]/page.jsx b/src/app/manga/[title]/[id]/[read]/page.jsx
new file mode 100644
index 0000000..a90d170
--- /dev/null
+++ b/src/app/manga/[title]/[id]/[read]/page.jsx
@@ -0,0 +1,51 @@
+import styles from "./read.module.css";
+import Image from "next/image";
+
+export default async function Read({ params }) {
+ const chapterId = params.read;
+ const data = await getPages(chapterId);
+ if (data.length === 0) {
+ return (
+ <div className={styles.NotFound}>
+ <p>
+ This chapter has no content. Please check the next chapter.
+ </p>
+ </div>
+ );
+ }
+
+ let images = [];
+ for (var i = 0; i < data.length; i++) {
+ var imgUrl = data[i].img;
+ images.push(imgUrl);
+ }
+
+ return (
+ <div className={styles.Main}>
+ <div className={styles.ImageContainer}>
+ {images &&
+ images.map((item, index) => (
+ <div className={styles.Image}>
+ <Image
+ src={`https://image-proxy-manga.vercel.app/image-proxy?url=${item}`}
+ key={index}
+ alt="Pages"
+ width={800}
+ height={1000}
+ priority
+ />
+ <p>{index + 1}</p>
+ </div>
+ ))}
+ </div>
+ </div>
+ );
+}
+
+async function getPages(id) {
+ const res = await fetch(
+ `https://consumet-api-di2e.onrender.com/meta/anilist-manga/read?chapterId=${id}&provider=mangadex`
+ );
+ const data = await res.json();
+ return data;
+}
diff --git a/src/app/manga/[title]/[id]/[read]/read.module.css b/src/app/manga/[title]/[id]/[read]/read.module.css
new file mode 100644
index 0000000..3a8c99f
--- /dev/null
+++ b/src/app/manga/[title]/[id]/[read]/read.module.css
@@ -0,0 +1,43 @@
+.ImageContainer img {
+ width: auto;
+ height: auto;
+ border-radius: 5px;
+ margin-top: 10px;
+
+}
+
+.Image {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background-color: #1b1b1b;
+ border-radius: 10px;
+ width: auto;
+ margin-top: 10px;
+}
+
+.ImageContainer p {
+ text-align: center;
+ color: white;
+ font-family: "Kanit";
+ font-size: 16px;
+ margin: 5px;
+}
+
+.NotFound {
+ text-align: center;
+ color: white;
+ font-family: "Atkinson Hyperlegible";
+ font-size: 20px;
+}
+
+@media screen and (max-width: 768px) {
+ .ImageContainer img {
+ width: 90%;
+ align-items: center;
+ }
+
+ .Image {
+ width: 100%;
+ }
+} \ No newline at end of file
diff --git a/src/app/manga/[title]/[id]/buttons.jsx b/src/app/manga/[title]/[id]/buttons.jsx
new file mode 100644
index 0000000..07fe3c3
--- /dev/null
+++ b/src/app/manga/[title]/[id]/buttons.jsx
@@ -0,0 +1,28 @@
+import styles from "./info.module.css";
+import Link from "next/link";
+
+export default async function Buttons({ content: data }) {
+ return (
+ <div className={styles.ChapterContainer}>
+ {data.chapters &&
+ data.chapters.map((item, index) => {
+ if (item.pages !== 0) {
+ return (
+ <Link
+ href={{
+ pathname: `/manga/info/read/${item.id}`,
+ query: {
+ name: item.title,
+ },
+ }}
+ >
+ <button key={index}>
+ {item.volumeNumber} - {item.chapterNumber}
+ </button>
+ </Link>
+ );
+ }
+ })}
+ </div>
+ );
+}
diff --git a/src/app/manga/[title]/[id]/info.module.css b/src/app/manga/[title]/[id]/info.module.css
new file mode 100644
index 0000000..99ea636
--- /dev/null
+++ b/src/app/manga/[title]/[id]/info.module.css
@@ -0,0 +1,135 @@
+.MangaInfoContainer {
+ max-width: 90%;
+ margin: 0px auto;
+}
+
+.MangaHero {
+ display: flex;
+ flex-direction: column;
+}
+
+.HeroImage {
+ width: 100%;
+ height: auto;
+ max-height: 550px;
+ border-radius: 10px;
+}
+
+.TitleContainer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 10px;
+}
+
+.TitleContainer p {
+ font-family: "Lato";
+ font-size: 32px;
+}
+
+.TitleContainer img {
+ border-radius: 10px;
+}
+
+.MangaDescription {
+ color: white;
+ font-family: "Atkinson Hyperlegible";
+ text-align: center;
+}
+
+.MangaDescription span {
+ margin: 10px;
+ color: var(--soft-purple);
+}
+
+.MangaRatings {
+ color: var(--light-green);
+}
+
+.MangaGenre {
+ background-color: #5f5f5f5d;
+ padding: 2px;
+ border-radius: 5px;
+ cursor: pointer;
+}
+
+.Character {
+ display: flex;
+ flex-direction: row;
+ overflow-x: auto;
+}
+
+.Character::-webkit-scrollbar {
+ height: 5px;
+}
+
+.Character::-webkit-scrollbar-thumb {
+ background-color: #949494;
+ border-radius: 5px;
+}
+
+.Character::-webkit-scrollbar-track {
+ background-color: rgb(87, 87, 87);
+ border-radius: 5px;
+}
+
+.CharacterEntry {
+ margin: 5px;
+}
+
+.CharacterEntry p {
+ text-align: center;
+ color: white;
+}
+
+.CharacterEntry img {
+ border-radius: 10px;
+}
+
+/* Chapters Buttons */
+.ChapterContainer {
+ width: 95%;
+ margin: 20px auto;
+ text-align: center;
+ height: 400px;
+ overflow-y: auto;
+}
+
+.ChapterContainer::-webkit-scrollbar {
+ width: 5px;
+}
+
+.ChapterContainer::-webkit-scrollbar-thumb {
+ background-color: #949494;
+ border-radius: 5px;
+}
+
+.ChapterContainer::-webkit-scrollbar-track {
+ background-color: rgb(66, 66, 66);
+ border-radius: 5px;
+}
+
+.ChapterContainer button {
+ width: 100px;
+ padding: 10px;
+ margin: 5px;
+ border-radius: 5px;
+ font-size: 16px;
+ border: none;
+ outline: none;
+ font-family: "Lato";
+ background-color: #41C9E2;
+ cursor: pointer;
+ transition: transform 0.2s linear;
+
+}
+
+.ChapterContainer button:hover {
+ background-color: var(--neon-green);
+}
+
+.ChapterContainer button:focus {
+ opacity: 0.6;
+ transition: transform 0.2s linear;
+ transform: scale(0.9);
+} \ No newline at end of file
diff --git a/src/app/manga/[title]/[id]/page.jsx b/src/app/manga/[title]/[id]/page.jsx
new file mode 100644
index 0000000..b41f719
--- /dev/null
+++ b/src/app/manga/[title]/[id]/page.jsx
@@ -0,0 +1,102 @@
+import styles from "./info.module.css";
+import Image from "next/image";
+import Buttons from "./buttons";
+
+export default async function MangaInfo({ params }) {
+ const id = params.id;
+ const data = await getMangaInfo(id);
+
+ return (
+ <div className={styles.MangaInfoContainer}>
+ {data && (
+ <div className={styles.MangaInfo}>
+ <div className={styles.MangaHero}>
+ <Image
+ src={data.cover}
+ width={1730}
+ height={400}
+ alt="Cover Poster"
+ className={styles.HeroImage}
+ priority
+ />
+ <div className={styles.TitleContainer}>
+ <p style={{ color: data.color }}>
+ {data.title["romaji"]}
+ </p>
+ <Image
+ src={data.image}
+ width={200}
+ height={310}
+ alt="Manga Poster"
+ priority
+ />
+ </div>
+ </div>
+
+ <div className={styles.MangaDescription}>
+ <p>{data.description.split("<br")[0]}</p>
+ <span className={styles.MangaReleaseYear}>
+ Released in: {data.releaseDate}
+ </span>
+ <span>
+ Started on: {data.startDate["day"]}-
+ {data.startDate["month"]}-{data.startDate["year"]}
+ </span>
+ <span>
+ Ended on: {data.endDate["day"]}-
+ {data.endDate["month"]}-{data.endDate["year"]}
+ </span>
+ <p className={styles.MangaRatings}>
+ Ratings: {data.rating / 10}
+ </p>
+ <p style={{ color: "#7ED7C1" }}>
+ Genres:
+ {data.genres &&
+ data.genres.map((item, index) => (
+ <span
+ key={index}
+ className={styles.MangaGenre}
+ style={{ color: data.color, margin: 5 }}
+ >
+ {item}
+ </span>
+ ))}
+ </p>
+ </div>
+
+ <div className={styles.CharactersContainer}>
+ <div className={styles.Character}>
+ {data.characters &&
+ data.characters.map((item, index) => (
+ <div
+ key={index}
+ className={styles.CharacterEntry}
+ >
+ <Image
+ src={item.image}
+ width={140}
+ height={200}
+ alt="Character Poster"
+ />
+ <p>
+ {item.name.full} ({item.role})
+ </p>
+ </div>
+ ))}
+ </div>
+ </div>
+
+ <Buttons content={data} />
+ </div>
+ )}
+ </div>
+ );
+}
+
+async function getMangaInfo(id) {
+ const res = await fetch(
+ `https://consumet-api-di2e.onrender.com/meta/anilist-manga/info/${id}?provider=mangadex`
+ );
+ const data = await res.json();
+ return data;
+}